﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Windows;
using CurvaLauncher.Utilities.Resources;


namespace CurvaLauncher.Services
{
    public class I18nService
    {
        private class I18nResourceDictionaries
        {
            public I18nResourceDictionaries(ResourceDictionary defaultDict, Dictionary<CultureInfo, ResourceDictionary> all)
            {
                Default = defaultDict;
                All = all;
            }

            public ResourceDictionary Default { get; private set; }
            public Dictionary<CultureInfo, ResourceDictionary> All { get; private set; }
        }

        private readonly IServiceProvider _serviceProvider;
    
        private ResourceDictionary _loadedDictionary;

        private readonly Dictionary<CultureInfo, ResourceDictionary> _resourceDictionaries = new Dictionary<CultureInfo, ResourceDictionary>
        {
            { new CultureInfo("en-US"), new ResourceDictionary { Source = GetResourceDictionaryPath("EnUs.xaml") } },
            { new CultureInfo("zh-Hans"), new ResourceDictionary { Source = GetResourceDictionaryPath("ZhHans.xaml") } },
            { new CultureInfo("zh-Hant"), new ResourceDictionary { Source = GetResourceDictionaryPath("ZhHant.xaml") } },
            { new CultureInfo("ja-JP"), new ResourceDictionary { Source = GetResourceDictionaryPath("JaJp.xaml") } },
            { new CultureInfo("de"), new ResourceDictionary { Source = GetResourceDictionaryPath("De.xaml") } },
        };

        private readonly Dictionary<Assembly, I18nResourceDictionaries> _assemblyResourceDictionaries = new Dictionary<Assembly, I18nResourceDictionaries>();

        public I18nService(  )
        {
        
          
         
        }

        private ResourceDictionary GetMatchedResourceDictionary(CultureInfo cultureInfo, Dictionary<CultureInfo, ResourceDictionary> resourceDictionaries)
        {
            foreach (var resourceKV in resourceDictionaries)
            {
                if (cultureInfo.Equals(resourceKV.Key))
                    return resourceKV.Value;
            }

            foreach (var resourceKV in resourceDictionaries)
            {
                if (cultureInfo.TwoLetterISOLanguageName.Equals(resourceKV.Key.TwoLetterISOLanguageName))
                    return resourceKV.Value;
            }

            return null;
        }

        private void ApplyResourceDictionary(ResourceDictionary resourceDictionary)
        {
            if (_loadedDictionary != null)
                Application.Current.Resources.MergedDictionaries.Remove(_loadedDictionary);

            Application.Current.Resources.MergedDictionaries.Add(resourceDictionary);
            _loadedDictionary = resourceDictionary;
        }

        private static Uri GetResourceDictionaryPath(string filename)
        {
            return new Uri($"pack://application:,,,/I18n/{filename}");
        }

        public CultureInfo CurrentCulture { get; private set; } = CultureInfo.CurrentCulture;

      

        public void ApplyLanguage(AppLanguage appLanguage)
        {
            
           

            switch (appLanguage)
            {
                case AppLanguage.English:
                    CurrentCulture = new CultureInfo("en");
                    break;
                case AppLanguage.ChineseSimplified:
                    CurrentCulture = new CultureInfo("zh-Hans");
                    break;
                case AppLanguage.ChineseTraditional:
                    CurrentCulture = new CultureInfo("zh-Hant");
                    break;
                case AppLanguage.Japanese:
                    CurrentCulture = new CultureInfo("ja-JP");
                    break;
                case AppLanguage.German:
                    CurrentCulture = new CultureInfo("de");
                    break;
                default:
                    CurrentCulture = CultureInfo.CurrentCulture;
                    break;
            }

            ResourceDictionary i18nDictionary = new ResourceDictionary();

            var resourceDictionary = GetMatchedResourceDictionary(CurrentCulture, _resourceDictionaries);
            if (resourceDictionary != null)
            {
                i18nDictionary.MergedDictionaries.Add(resourceDictionary);
            }

            foreach (var assemblyResourceDictionariesKV in _assemblyResourceDictionaries)
            {
                var assemblyResourceDictionary = GetMatchedResourceDictionary(CurrentCulture, assemblyResourceDictionariesKV.Value.All);
                if (assemblyResourceDictionary != null)
                {
                    i18nDictionary.MergedDictionaries.Add(new AssemblyResourceDictionary(assemblyResourceDictionariesKV.Key, assemblyResourceDictionary));
                }
                else
                {
                    i18nDictionary.MergedDictionaries.Add(new AssemblyResourceDictionary(assemblyResourceDictionariesKV.Key, assemblyResourceDictionariesKV.Value.Default));
                }
            }

            ApplyResourceDictionary(i18nDictionary);
            OnCurrentCultureChanged();
        }

        public void AddAssemblyResourceDictionary(Assembly assembly, CultureInfo cultureInfo, ResourceDictionary resourceDictionary)
        {
            if (!_assemblyResourceDictionaries.TryGetValue(assembly, out var dicts))
            {
                dicts = new I18nResourceDictionaries(resourceDictionary, new Dictionary<CultureInfo, ResourceDictionary>());
                _assemblyResourceDictionaries[assembly] = dicts;
            }

            dicts.All[cultureInfo] = resourceDictionary;
        }

        private void OnCurrentCultureChanged()
        {
            var handler = CurrentCultureChanged;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }

        public event EventHandler CurrentCultureChanged;
    }
    public enum AppLanguage
    {
        [Description("系统选择")]
        Auto,

        [Description("英文")]
        English,

        [Description("简体中文")]
        ChineseSimplified,

        [Description("日本語")]
        Japanese,

        [Description("繁体中文")]
        ChineseTraditional,

     

        [Description("Deutsch")]
        German
    }
}
